# miaoma/springboot/gen_java_code.py

import os
from dataclasses import asdict
from src.base import bera
from miaoma.models.springboot_meta_info import SpringBootTableMetaInfo
from jinja2 import Environment
from src.base import truncate_reverse_filter

# 生成 Java 实体类代码
def generate_entity_code(table_meta: SpringBootTableMetaInfo, templates: Environment, project_root_dir, package_path):
    # 创建实体类目录
    output_folder = os.path.join(project_root_dir, "src/main/java", package_path, 'entity')
    os.makedirs(output_folder, exist_ok=True)

    # 渲染 Entity 模板
    entity_code = templates.get_template('springboot/java_entity.j2').render(asdict(table_meta))
    entity_file_name = f"{table_meta.class_name}.java"  # 使用类名生成文件名
    entity_path = os.path.join(output_folder, entity_file_name)

    # 写入 Entity 文件
    with open(entity_path, 'w') as f:
        f.write(entity_code)
    bera.logger.info(f"Generated Entity code for {table_meta.class_name} at {truncate_reverse_filter(entity_path)}")

# 生成 Java Mapper 接口代码
def generate_mapper_code(table_meta: SpringBootTableMetaInfo, templates: Environment, project_root_dir, package_path):
    output_folder = os.path.join(project_root_dir, "src/main/java", package_path, 'mapper')
    os.makedirs(output_folder, exist_ok=True)
    mapper_code = templates.get_template('springboot/java_mapper.j2').render(asdict(table_meta))
    mapper_file_name = f"{table_meta.class_name}Mapper.java"
    mapper_path = os.path.join(output_folder, mapper_file_name)
    with open(mapper_path, 'w') as f:
        f.write(mapper_code)
    bera.logger.info(f"Generated Mapper code for {table_meta.class_name} at {truncate_reverse_filter(mapper_path)}")

# 生成 Java Service 接口和实现类代码
def generate_service_code(table_meta: SpringBootTableMetaInfo, templates: Environment, project_root_dir, package_path):
    output_folder = os.path.join(project_root_dir, "src/main/java", package_path, 'service')
    os.makedirs(output_folder, exist_ok=True)
    service_code = templates.get_template('springboot/java_service.j2').render(asdict(table_meta))
    service_file_name = f"{table_meta.class_name}Service.java"
    service_path = os.path.join(output_folder, service_file_name)
    with open(service_path, 'w') as f:
        f.write(service_code)
    bera.logger.info(f"Generated Service interface code for {table_meta.class_name} at {truncate_reverse_filter(service_path)}")

    output_folder = os.path.join(output_folder, 'impl')
    os.makedirs(output_folder, exist_ok=True)
    service_impl_code = templates.get_template('springboot/java_service_impl.j2').render(asdict(table_meta))
    service_impl_file_name = f"{table_meta.class_name}ServiceImpl.java"
    service_impl_path = os.path.join(output_folder, service_impl_file_name)
    with open(service_impl_path, 'w') as f:
        f.write(service_impl_code)
    bera.logger.info(f"Generated ServiceImpl code for {table_meta.class_name} at {truncate_reverse_filter(service_impl_path)}")

# 生成 Java Controller 类代码
def generate_controller_code(table_meta: SpringBootTableMetaInfo, templates: Environment, project_root_dir, package_path):
    output_folder = os.path.join(project_root_dir, "src/main/java", package_path, 'controller')
    os.makedirs(output_folder, exist_ok=True)
    controller_code = templates.get_template('springboot/java_controller.j2').render(asdict(table_meta))
    controller_file_name = f"{table_meta.class_name}Controller.java"
    controller_path = os.path.join(output_folder, controller_file_name)
    with open(controller_path, 'w') as f:
        f.write(controller_code)
    bera.logger.info(f"Generated Controller code for {table_meta.class_name} at {truncate_reverse_filter(controller_path)}")

# 生成 Java Application 主程序代码
def generate_application_code(table_meta: SpringBootTableMetaInfo, templates: Environment, project_root_dir, package_path):
    # Application 文件通常放在根包路径下
    output_folder = os.path.join(project_root_dir, "src/main/java", package_path)
    os.makedirs(output_folder, exist_ok=True)

    # 渲染 Application 模板
    application_code = templates.get_template('springboot/java_application.j2').render(asdict(table_meta))
    application_file_name = "Application.java"
    application_path = os.path.join(output_folder, application_file_name)
    with open(application_path, 'w') as f:
        f.write(application_code)
    bera.logger.info(f"Generated Application code at {truncate_reverse_filter(application_path)}")

# 生成 Resource Config Printer 主程序代码
def generate_resource_config_printer_code(table_meta: SpringBootTableMetaInfo, templates: Environment, project_root_dir, package_path):
    # Resource Config Printer 文件通常放在根包路径下
    output_folder = os.path.join(project_root_dir, "src/main/java", package_path)
    os.makedirs(output_folder, exist_ok=True)

    # 渲染 Resource Config Printer  模板
    resource_config_printer_code = templates.get_template('springboot/java_resource_config_printer.j2').render(asdict(table_meta))
    resource_config_printer_file_name = "ResourceConfigPrinter.java"
    resource_config_printer_path = os.path.join(output_folder, resource_config_printer_file_name)
    with open(resource_config_printer_path, 'w') as f:
        f.write(resource_config_printer_code)
    bera.logger.info(f"Generated Resource Config Printer code at {truncate_reverse_filter(resource_config_printer_path)}")

# 生成 dto 代码
def generate_dto_code(table_meta: SpringBootTableMetaInfo, templates: Environment, project_root_dir, package_path):
    output_folder = os.path.join(project_root_dir, "src/main/java", package_path, 'dto')
    os.makedirs(output_folder, exist_ok=True)

    # 渲染 ApiResponse 模板
    api_response_code = templates.get_template('springboot/java_api_response.j2').render(asdict(table_meta))
    api_response_path = os.path.join(output_folder, 'ApiResponse.java')
    with open(api_response_path, 'w') as f:
        f.write(api_response_code)
    bera.logger.info(f"Generated ApiResponse code at {truncate_reverse_filter(api_response_path)}")

    # 渲染 MybatisPlusConfig 模板
    error_code_code = templates.get_template('springboot/java_error_code.j2').render(asdict(table_meta))
    error_code_path = os.path.join(output_folder, 'ErrorCode.java')
    with open(error_code_path, 'w') as f:
        f.write(error_code_code)
    bera.logger.info(f"Generated ErrorCode code at {truncate_reverse_filter(error_code_path)}")

# 生成 aspect 代码
def generate_aspect_code(table_meta: SpringBootTableMetaInfo, templates: Environment, project_root_dir, package_path):
    output_folder = os.path.join(project_root_dir, "src/main/java", package_path, 'aspect')
    os.makedirs(output_folder, exist_ok=True)

    # 渲染 ApiResponseAspect 模板
    api_response_aspect_code = templates.get_template('springboot/java_api_response_aespect.j2').render(asdict(table_meta))
    api_response_aspect_path = os.path.join(output_folder, 'ApiResponseAspect.java')
    with open(api_response_aspect_path, 'w') as f:
        f.write(api_response_aspect_code)
    bera.logger.info(f"Generated ApiResponseAspect code at {truncate_reverse_filter(api_response_aspect_path)}")

# 生成annotation 代码
def generate_annotation_code(table_meta: SpringBootTableMetaInfo, templates: Environment, project_root_dir, package_path):
    output_folder = os.path.join(project_root_dir, "src/main/java", package_path, 'annotation')
    os.makedirs(output_folder, exist_ok=True)

    # 渲染 ApiResponseWrapper 模板
    api_response_wrapper_code = templates.get_template('springboot/java_api_response_wrapper.j2').render(asdict(table_meta))
    api_response_wrapper_path = os.path.join(output_folder, 'ApiResponseWrapper.java')
    with open(api_response_wrapper_path, 'w') as f:
        f.write(api_response_wrapper_code)
    bera.logger.info(f"Generated ApiResponseWrapper code at {truncate_reverse_filter(api_response_wrapper_path)}")

# 生成 Config 代码
def generate_config_code(table_meta: SpringBootTableMetaInfo, templates: Environment, project_root_dir, package_path):
    output_folder = os.path.join(project_root_dir, "src/main/java", package_path, 'config')
    os.makedirs(output_folder, exist_ok=True)

    # 渲染 AppConfig 模板
    app_config_code = templates.get_template('springboot/java_app_config.j2').render(asdict(table_meta))
    app_config_path = os.path.join(output_folder, 'AppConfig.java')
    with open(app_config_path, 'w') as f:
        f.write(app_config_code)
    bera.logger.info(f"Generated AppConfig code at {truncate_reverse_filter(app_config_path)}")

    # 渲染 MybatisPlusConfig 模板
    mybatis_config_code = templates.get_template('springboot/java_mybatis_plus_config.j2').render(asdict(table_meta))
    mybatis_config_path = os.path.join(output_folder, 'MybatisPlusConfig.java')
    with open(mybatis_config_path, 'w') as f:
        f.write(mybatis_config_code)
    bera.logger.info(f"Generated MybatisPlusConfig code at {truncate_reverse_filter(mybatis_config_path)}")

# 生成 Java 代码（包括 Entity、Mapper、Service、ServiceImpl、Controller 和 Application）
def generate_java_code(table_meta: SpringBootTableMetaInfo, templates: Environment, project_dir='artifacts/miaoma/springboot'):
    # 测试项目根目录
    test_project_folder = 'artifacts/miaoma/springboot'

    # 真实项目根目录
    real_project_folder = os.path.join(bera.get_variable("home_directory"), "workspace/bera/beracode/manager")

    # Java 源码文件夹路径
    project_root_dir = real_project_folder

    # 生成包目录路径
    package_path = table_meta.java_package_name.replace('.', '/')

    # 生成 Entity 类代码
    generate_entity_code(table_meta, templates, project_root_dir, package_path)

    # 生成 Mapper 接口代码
    generate_mapper_code(table_meta, templates, project_root_dir, package_path)

    # 生成 Service 接口和实现类代码
    generate_service_code(table_meta, templates, project_root_dir, package_path)

    # 生成 Controller 类代码
    generate_controller_code(table_meta, templates, project_root_dir, package_path)

    # 生成 Application 主程序代码
    generate_application_code(table_meta, templates, project_root_dir, package_path)

    # 生成 Config 代码
    generate_config_code(table_meta, templates, project_root_dir, package_path)

    # 生成 dto 代码
    generate_dto_code(table_meta, templates, project_root_dir, package_path)

    # 生成 aspect 代码
    generate_aspect_code(table_meta, templates, project_root_dir, package_path)

    # 生成 annotation 代码
    generate_annotation_code(table_meta, templates, project_root_dir, package_path)

    # 生成 Resource Config Printer 代码
    generate_resource_config_printer_code(table_meta, templates, project_root_dir, package_path)

    bera.logger.info("Generated all Java code successfully.")